/*
 * NAME, etc.
 *
 * sync.h
 */

#ifndef _STHREAD_SYNC_H_
#define _STHREAD_SYNC_H_

//#include "/usr/src/linux-2.6.11.12-hmwk3/linux-2.6.11.12/include/linux/list.h"

typedef struct sthread_list {
	sthread_t* thread;
	struct sthread_list* next;
} sthread_list_t;

sthread_list_t* add_thread(sthread_list_t* p_head, sthread_t* p_sth) {
    sthread_list_t* head = p_head;

    if (p_head != NULL) {
		while (p_head->next != NULL)
			p_head = p_head->next;
		
		p_head->next   = (struct sthread_list_t*) malloc(sizeof(sthread_list_t));
		p_head         = p_head->next;
		p_head->next   = NULL;
		p_head->thread = p_sth;
		
		return head;
    }

    else {
		p_head         = (struct sthread_list_t*) malloc(sizeof(sthread_list_t));
		p_head->next   = NULL;
		p_head->thread = p_sth;
		
		return p_head;
    }
}

sthread_list_t* pop_thread(sthread_list_t* p_head) {
    sthread_list_t* t_l;
    t_l = p_head->next;
    
	free(p_head);
    
	return t_l;	
}

int destroy_sthread_list(sthread_list_t* p_head) {
    while (p_head != NULL)
		p_head = pop_thread(p_head);

	return 0;
}

typedef struct sthread_sem_struct {
  int    count;
  int    lock;
  int	 n_waiting;
  struct sthread_list wait_queue;
} sthread_sem_t;

int sthread_list_init(sthread_list_t* p_sth_list, sthread_t* p_sth);
int sthread_sem_init(sthread_sem_t *sem, int count);
int sthread_sem_destroy(sthread_sem_t *sem);
int sthread_sem_down(sthread_sem_t *sem);
int sthread_sem_try_down(sthread_sem_t *sem);
int sthread_sem_up(sthread_sem_t *sem);

#endif
